const { ccclass, property } = cc._decorator;

enum Direction {
    up = 0,
    down = 1,
    left = 2,
    right = 3
}

@ccclass
export default class HeroSetzIndex extends cc.Component {
    @property(cc.Node)
    heroRootNode: cc.Node = null;
    TrackUuid: string = "";
    zIndexDown: Map<string, number> = new Map<string, number>();
    zIndexUp: Map<string, number> = new Map<string, number>();
    onLoad() {
        this.heroRootNode = this.node.parent.parent;
    }
    start() {
        let area = this.node.addComponent(cc.BoxCollider);
        area.tag = 0;
        let size = this.node.getContentSize();
        area.size = new cc.Size(size.width + 10, size.height + 10);
    }

    onCollisionEnter(other, self) {
        if (self.tag != 0)
            return;
        if (other.tag == TagWayTrack || other.tag == TagWayBody1 || other.tag == TagWayBody2 || other.tag == TagBox || other.tag == TagStep) {
            let dir;
            if (other.tag == TagWayTrack) {
                dir = Direction.down;
                this.TrackUuid = other.uuid;
            }
            else if (this.TrackUuid == other.uuid) {
                return;
            }
            else
                dir = this.getDirection(other, self);

            let otherNode = other.node;
            if (other.tag == TagStep)
                otherNode = other.node.parent;

            if (dir == Direction.down || dir == Direction.left) {
                this.zIndexDown.set(otherNode.uuid, otherNode.zIndex);
                if (this.zIndexUp.has(otherNode.uuid))
                    this.zIndexUp.delete(otherNode.uuid);
            }
            else {
                this.zIndexUp.set(otherNode.uuid, otherNode.zIndex);
                if (this.zIndexDown.has(otherNode.uuid))
                    this.zIndexDown.delete(otherNode.uuid);
            }
            this.setzIndex(dir);
        }
    }
    setzIndex(dir: Direction) {
        if (dir == Direction.down || dir == Direction.left) {
            let downMax = this.getMax(this.zIndexDown);
            if (downMax)
                this.heroRootNode.zIndex = downMax + 1;
        }
        else {
            let upMin = this.getMin(this.zIndexUp);
            if (upMin)
                this.heroRootNode.zIndex = upMin - 1;
        }
    }
    getMin(list: any): number {
        let index = cc.macro.MAX_ZINDEX;
        list.forEach(element => {
            if (index > element)
                index = element;
        });
        if (index == cc.macro.MAX_ZINDEX)
            return null;
        return index;
    }
    getMax(list: any): number {
        let index = cc.macro.MIN_ZINDEX;
        list.forEach(element => {
            if (index < element)
                index = element;
        });
        if (index == cc.macro.MIN_ZINDEX)
            return null;
        return index;
    }
    //碰撞物体相对于Hero的方位
    getDirection(other, self): Direction {
        if (other.world.aabb.yMax > self.world.aabb.yMin && other.world.aabb.yMin < self.world.aabb.yMax) {
            if (other.world.aabb.xMin >= self.world.aabb.xMax - 10)
                return Direction.right;
            else if (other.world.aabb.xMax <= self.world.aabb.xMin + 10)
                return Direction.left;
            else if (other.world.aabb.yMin > self.world.aabb.yMax - 20)
                return Direction.up;
            else
                return Direction.down;
        }
        else {
            if (other.world.aabb.yMin > self.world.aabb.yMax - 10)
                return Direction.up;
            else
                return Direction.down;
        }
    }
    onCollisionExit(other, self) {
        if (self.tag != 0)
            return;
        if (other.tag == TagWayBody1 || other.tag == TagWayBody2 || other.tag == TagBox || other.tag == TagStep) {
            this.zIndexUp.delete(other.node.uuid);
            this.zIndexDown.delete(other.node.uuid);
        }
    }
}
